/*  Copyright (C) 2016 Nate Dobbins
 *
 *  This program is free software: you can redistribute it and/or modify it under the terms of the
 *  GNU General Public License as published by the Free Software Foundation version 3 of the
 *  License.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *  the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with this program.  If
 *  not, see <http://www.gnu.org/licenses/>.
 */

package main

import (
	"flag"
	"fmt"
	"github.com/blevesearch/bleve"
	"io/ioutil" // for temp dir/files to store index
	"os"
	"strings"
	// "net/http" // for DetectContentType to skip bins
)

type data struct {
	Filename string
	Content  string
}

var indexLoc = os.TempDir() + string(os.PathSeparator) + "sift"
var mapping = bleve.NewIndexMapping()
var idx, _ = bleve.New(indexLoc, mapping)

func flags() (bool, bool) {

	exact := flag.Bool("e", false, "search exact strings")
	recursive := flag.Bool("r", false, "search within contained directories")

	flag.Parse()

	return *exact, *recursive

}

func args() (string, string) {

	args := flag.Args()

	// not enough or too many args
	if len(args) < 1 || len(args) > 2 {
		flag.Usage() // todo: exit with err
	}

	q := args[0]

	var path string
	if len(args) < 2 {
		path = "."
	} else {
		path = args[1]
	}

	// add trailing path separator if it's not there
	if strings.HasSuffix(path, string(os.PathSeparator)) == false {
		path += string(os.PathSeparator)
	}

	return q, path

}

func indexFiles(path string, recursive bool) {

	files, err := ioutil.ReadDir(path)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, file := range files {
		if file.IsDir() {
			if recursive {
				indexFiles(path+file.Name()+string(os.PathSeparator), true)
			}
		} else {
			content, err := ioutil.ReadFile(path + string(os.PathSeparator) + file.Name())
			if err != nil {
				fmt.Println(err)
			}
			idx.Index(file.Name(), data{Filename: file.Name(), Content: string(content)})
		}
	}

}

func search(q string) {

	// delete prior index if it exists
	if _, err := os.Stat(indexLoc); err == nil {
		err = os.RemoveAll(indexLoc)
		if err != nil {
			fmt.Println(err)
		}
	}

	query := bleve.NewMatchQuery(q)
	search := bleve.NewSearchRequest(query)
	searchResults, err := idx.Search(search)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(searchResults)

}

func main() {

	exact, recursive := flags()
	fmt.Println(exact, recursive) // todo
	q, path := args()
	indexFiles(path, recursive)
	search(q)

}
